#include "gkt_board.h"
#include "gkt_debug.h"
#include "gkt_driver.h"
#include "gkt_rtc.h"
#include "gkt_flash_partition.h"
#include "gkt_user.h"
#include "gkt_record_unlock.h"
#include "gkt_door.h"
#include "window_common.h"
#include "gkt_os.h"
#include "gkt_bg_job.h"
#include "gkt_fpsensor.h"
#include "gkt_gpio.h"
#include "gkt_driver.h"
#include "gkt_rfid.h"
#include "gkt_backboard.h"
#include "gkt_wdt.h"
#include "gkt_adc.h"
#include "gkt_battery.h"
#include "gkt_lighting_effect.h"
#include "gkt_version.h"
#include "gkt_wakeup.h"
#if	defined(GKT_CONFIG_PROXIMITY_SENSOR_ENABLE)&&(GKT_CONFIG_PROXIMITY_SENSOR_ENABLE)
#include "gkt_pr_sensor.h"
#endif
#include "gkt_card.h"

#if defined(GKT_CONFIG_RTC_DISABLE) && GKT_CONFIG_RTC_DISABLE
#define check_or_set_default_date_time()	do {} while(0)
#else
static void check_or_set_default_date_time(void)
{
	gkt_date_time_s dt;
	int retval;

	retval = gkt_rtc_get_time(&dt);
	if (GKT_SUCCESS == retval) {
		retval = gkt_dt_check_date(&dt.date);
		if (!retval)
			goto set_default_dt;

		retval = gkt_dt_check_time(&dt.time);
		if (!retval)
			goto set_default_dt;

		return;
	}
	else if (GKT_EAGAIN == retval)
		return;

set_default_dt:
	dt.date.year = GKT_WINDOW_DATE_YEAR_DEFAULT;
	dt.date.month = GKT_DT_MONTH_JAN;
	dt.date.day = 1;
	dt.time.hour = 0;
	dt.time.minute = 0;
	dt.time.second = 0;
	gkt_rtc_set_time(&dt);
}
#endif

#define WINDOW_BG_JOB_SYNC_UNIT	10
#define WINDOW_BG_JOB_SYNC_TIMEOUT	3000

#if defined(GKT_CONFIG_WDTE_ENABLE) && GKT_CONFIG_WDTE_ENABLE
#include "gkt_wdt.h"
#define app_main_wdt_feed()	gkt_wdt_feed()
#else
#define app_main_wdt_feed()	do {} while (0)
#endif

void gkt_app_main(void *params)
{
	int retval;
	uint32_t value;
	
	gkt_trace("app_main: start ...\n");

	gkt_bg_job_init();
	check_or_set_default_date_time();
	app_main_wdt_feed();

#if defined(GKT_CONFIG_BACKBOARD_ENABLE) && GKT_CONFIG_BACKBOARD_ENABLE
	retval = gkt_backboard_init();
	if (retval != GKT_SUCCESS) {
		gkt_error("app_main: backboard init failed %d\n", retval);
		return;
	}
#endif

	retval = gkt_flash_partition_init();
	if (retval != GKT_SUCCESS) {
		gkt_error("app_main: flash partition init failed %d\n", retval);
		return;
	}

	/* window data */
	window_data_init();

	BPK_ReadKey(&value, 1, GKT_RETMEM_ALWAYS_MODE_STATUS);
	g_window_retmem_data.always_open_enabled = value;
	gkt_window_system_door_set_always_open_state(
			g_window_retmem_data.always_open_enabled);

	if (gp_window_unreset_data->keypad_parameter_value == 0) {
		if (GKT_KEYPAD_PAPAMETERS == GKT_KEYPAD_PAPAMETERS_STANDARD) {
			gkt_printf("key used standard param\n");
			gp_window_unreset_data->keypad_parameter_value = GKT_KEYPAD_RESPONSE_STANDARD;
		}
		else {
			gkt_printf("key used sensitivity param\n");
			gp_window_unreset_data->keypad_parameter_value = GKT_KEYPAD_RESPONSE_SENSITIVITY;
		}
		gkt_key_parameter_update(gp_window_unreset_data->keypad_parameter_value);
	}
	else {
		if (gp_window_unreset_data->keypad_parameter_value == GKT_KEYPAD_RESPONSE_SENSITIVITY)
			gkt_printf("key used sensitivity param\n");
		else
			gkt_printf("key used standard param\n");
		gkt_key_parameter_update(gp_window_unreset_data->keypad_parameter_value);
	}

	/* led */
	gkt_led_init();
	gkt_ambient_light_init();

	/* user manager init */
	gkt_user_init();
#if	defined(GKT_CONFIG_PROXIMITY_SENSOR_ENABLE)	\
		&&(GKT_CONFIG_PROXIMITY_SENSOR_ENABLE)
	if (GKT_SYSTEM_RESET_WAKEUP != g_system_info.reset_mode){
		g_window_retmem_data.pr_power_state = SENSE_PR_POWER_ON;
		g_window_retmem_data.pr_power_cnt = 0;
		g_window_retmem_data.pr_power_clear_dtu = 0;
		gkt_pr_sensor_handle();
	}
#endif
	/* unlock record model init */
	gkt_record_unlock_init();

#if defined(GKT_CONFIG_MULTIPLE_LANGUAGE_SUPPORT) && GKT_CONFIG_MULTIPLE_LANGUAGE_SUPPORT
	/* init language */
	gkt_language_config(gp_window_data->language);
#endif

#if defined(GKT_CONFIG_RFID_ENABLE) && GKT_CONFIG_RFID_ENABLE	\
	&& defined (GKT_CONFIG_RFID_YC5018) && GKT_CONFIG_RFID_YC5018
	if (gp_window_unreset_data->yc_rfid_gain != 0)
		gkt_rfid_factory_gain_set(gp_window_unreset_data->yc_rfid_gain);
	if (gp_window_unreset_data->yc_rfid_water_level_factory != 0) 
		gkt_rfid_factory_water_level_set(gp_window_unreset_data->yc_rfid_water_level_factory);
#endif

	/* init window manager */
	retval = gkt_window_manager_init();
	if (retval != GKT_SUCCESS) {
		gkt_error("app_main: window manager init failed!\n");
		return;
	}

	/* init voice */
#if !GKT_VOICE_OUTPUT_VOLUME_DISABLE
	if (gp_window_data->voice_volume >= GKT_VOICE_OUTPUT_VOLUME_MAX)
		gp_window_data->voice_volume = GKT_VOICE_OUTPUT_VOLUME_DEFAULT;
	gkt_voice_output_set_volume(gp_window_data->voice_volume);
#endif
	window_voice_combined_init();

	/* door lock */
#if defined(GKT_CONFIG_DOOR_TAMPER_ENABLE) && GKT_CONFIG_DOOR_TAMPER_ENABLE
		if (!gp_window_data->door_tamper_alarm_enable) {
			gkt_gpio_interrupt_clear(GKT_CONFIG_DOOR_TAMPER0_GPIO_PIN);
#if defined(GKT_CONFIG_DOOR_TAMPER1_GPIO_PIN)
			gkt_gpio_interrupt_clear(GKT_CONFIG_DOOR_TAMPER1_GPIO_PIN);
#endif			
		}
#endif
#if defined(GKT_CONFIG_DOOR_LOCK_ENABLE) && GKT_CONFIG_DOOR_LOCK_ENABLE			
#if !GKT_DOOR_LOCK_MOTOR_ROTATE_DIRECTION_FIXED
		gkt_door_lock_set_motor_rotate_direction(
			gp_window_unreset_data->lock_motor_rotate_direction);
#endif
#endif		
#if !GKT_DOOR_LOCK_MOTOR_ROTATE_TIME_FIXED
		gkt_door_lock_set_motor_rotate_time(0,
			gp_window_unreset_data->lock_motor_rotate_time_ms);
#endif
#if defined(GKT_CONFIG_DOOR_LOCK_AUTOMATIC) && GKT_CONFIG_DOOR_LOCK_AUTOMATIC
		gkt_door_lock_set_motor_rotate_time(1,
			gp_window_unreset_data->lock_motor_full_rotate_time_ms);
#if (GKT_MODULE_LOC_BACKBOARD == GKT_DOOR_LOCK_LOCATION)
		retval = gkt_door_lock_set_auto_close_time(1, gp_window_data->lock_auto_double_close_time);
		if (GKT_EINPROCESS != retval)
			gkt_error("app_main: gkt_door_lock_set_auto_close_time failed!\n");
#endif
#if (GKT_MODULE_LOC_FRONTBOARD == GKT_DOOR_LOCK_LOCATION)
		if (gp_window_unreset_data->lock_motor_self_learn_complete) {
			gkt_door_lock_set_motor_locked_rotor_voltage(
				gp_window_unreset_data->lock_motor_locked_rotor_voltage);
		}
#endif
#endif

	/* save data if need */
	window_data_save();
	
	if (g_system_info.reset_mode != GKT_SYSTEM_RESET_WAKEUP) {
		int sync_complete, timeout_left;

#if !defined(GKT_CONFIG_DOOR_LOCK_AUTOMATIC) \
	|| !GKT_CONFIG_DOOR_LOCK_AUTOMATIC
		uint32_t lock_status = gkt_door_lock_get_status();
		if (lock_status != GKT_DOOR_LOCK_ST_CLOSED) {
			gkt_printf("app_main: close lock ...\n");
			gkt_door_lock_close(0);
		}
#endif
#if	defined(GKT_CONFIG_PROXIMITY_SENSOR_ENABLE)	&& (GKT_CONFIG_PROXIMITY_SENSOR_ENABLE)
		gkt_pr_sensor_set_threshold(gp_window_data->pr_sensor_state, 0);
#endif
		gkt_bg_job_enable();
		app_main_wdt_feed();

		timeout_left = WINDOW_BG_JOB_SYNC_TIMEOUT;
		do {
			sync_complete = gkt_bg_job_sync_complete();
			if (sync_complete)
				break;

			gkt_thread_sleep(WINDOW_BG_JOB_SYNC_UNIT);
			timeout_left -= WINDOW_BG_JOB_SYNC_UNIT;
		} while (timeout_left > 0);
		gkt_info("app_main: sync bg_job complete!\n");

		app_main_wdt_feed();
	}
	else
		gkt_bg_job_enable();

	//gkt_driver_clock_aon_32k_measure_control(1, 0);

	/* start window manager & show welcome window */
	gkt_window_manager_start(WINDOW_ID_welcome);

	GKT_ASSERT(0);
}

void gkt_app_lphook(int when, int mode)
{
	int retval=GKT_SUCCESS;
	
#if GKT_CONFIG_VOICE_OUTPUT_ENABLE
	gkt_voice_output_stop();
#endif
	
#if defined(GKT_CONFIG_SLIDING_CLOSURE_MAGNET_LEVEL)
	gkt_sliding_closure_magnet_control(0);
#endif	
	
#if defined(GKT_CONFIG_AMBIENT_LIGHT_ENABLE) && GKT_CONFIG_AMBIENT_LIGHT_ENABLE
	gkt_ambient_light_set_state(GKT_AMBIENT_LIGHT_STATE_OFF, 0, 0);
#endif

#if defined(GKT_CONFIG_RFID_ENABLE) && GKT_CONFIG_RFID_ENABLE
	gkt_event_mask_single(GKT_EVENT_CARD, 0);
#endif

#if defined(GKT_CONFIG_KEY_WAKEUP_NO_CALIBRATE) && GKT_CONFIG_KEY_WAKEUP_NO_CALIBRATE
	if (GKT_DRIVER_LP_NORMAL == gkt_driver_get_lp_mode()) {
		gkt_thread_sleep(10);
		gkt_keypad_control(GKT_KEYPAD_CTRL_ENABLE, 0);
		gkt_keypad_update_backup_freq();
	}
#endif

	gkt_key_led_control(GKT_KEY_LED_CTRL_ENABLE, 0);
	gkt_led_standby();
#if defined GKT_CONFIG_AMBIENT_LIGHT_META_2_GPIO_PIN 	
	gkt_ambient_light_standby();
#endif
	gkt_door_lock_standby();
	gkt_adc_standby();
	gkt_lighting_effect_standby();

#if defined(GKT_CONFIG_INTERNAL_DOORBELL_ENABLE) && GKT_CONFIG_INTERNAL_DOORBELL_ENABLE
	gkt_gpio_config(GKT_CONFIG_INTERNAL_DOORBELL_GPIO_PIN, GKT_GPIO_F_OUTPUT, NULL);
	gkt_gpio_set_pin_level(GKT_CONFIG_INTERNAL_DOORBELL_GPIO_PIN, 0);
#endif

	if (GKT_CONFIG_VOICE_OUTPUT_OPAMP_EN_PIN != GKT_CONFIG_DEVICE_POWER_CTRL_PIN) {
		gkt_voice_output_disable_opamp();
		gkt_thread_sleep(20);
	}

#if !defined(GKT_CONFIG_DEVICE_POWER_CTRL_DOWN_DELAYED)	\
	|| !GKT_CONFIG_DEVICE_POWER_CTRL_DOWN_DELAYED
	gkt_driver_device_power_down();
#endif

#if !defined(GKT_CONFIG_SCREEN_ENABLE) || !GKT_CONFIG_SCREEN_ENABLE
#if defined(GKT_CONFIG_SCREEN_RESET_GPIO_PIN)
	retval = gkt_gpio_config(GKT_CONFIG_SCREEN_RESET_GPIO_PIN, 
						GKT_GPIO_F_OUTPUT, NULL);
	if (retval != GKT_SUCCESS) {
		gkt_error("screen standby: config reset pin failed: %d\n", retval);
	}
	gkt_gpio_set_pin_level(GKT_CONFIG_SCREEN_RESET_GPIO_PIN, 0);
#endif

#if defined(GKT_CONFIG_SCREEN_CD_PIN)
	retval = gkt_gpio_config(GKT_CONFIG_SCREEN_CD_PIN, 
						GKT_GPIO_F_OUTPUT, NULL);
	if (retval != GKT_SUCCESS) 
		gkt_error("screen standby: config cd pin failed: %d\n", retval);
	gkt_gpio_set_pin_level(GKT_CONFIG_SCREEN_CD_PIN, 0);
#endif

#if defined(GKT_CONFIG_SCREEN_CS_PIN)
	retval = gkt_gpio_config(GKT_CONFIG_SCREEN_CS_PIN, 
						GKT_GPIO_F_OUTPUT, NULL);
	if (retval != GKT_SUCCESS) 
		gkt_error("screen standby: config cs pin failed: %d\n", retval);
	gkt_gpio_set_pin_level(GKT_CONFIG_SCREEN_CS_PIN, 0);
#endif

#if defined(GKT_CONFIG_SCREEN_SCK_PIN)
	retval = gkt_gpio_config(GKT_CONFIG_SCREEN_SCK_PIN, 
						GKT_GPIO_F_OUTPUT, NULL);
	if (retval != GKT_SUCCESS) 
		gkt_error("screen standby: config clock pin failed: %d\n", retval);
	gkt_gpio_set_pin_level(GKT_CONFIG_SCREEN_SCK_PIN, 0);
#endif

#if defined(GKT_CONFIG_SCREEN_MOSI_PIN)
	retval = gkt_gpio_config(GKT_CONFIG_SCREEN_MOSI_PIN, 
						GKT_GPIO_F_OUTPUT, NULL);
	if (retval != GKT_SUCCESS) 
		gkt_error("screen standby: config mosi pin failed: %d\n", retval);
	gkt_gpio_set_pin_level(GKT_CONFIG_SCREEN_MOSI_PIN, 0);
#endif
#endif

#if defined(GKT_CONFIG_DAC_OUTPUT_P_PIN)
	gkt_thread_sleep(100);
	retval = gkt_gpio_config(GKT_CONFIG_DAC_OUTPUT_P_PIN, GKT_GPIO_F_OUTPUT, NULL);
	if (retval != GKT_SUCCESS)
		gkt_error("DAC_OUTPUT_P_PAD_PIN config output err=%d\n",retval);
	gkt_gpio_set_pin_level(GKT_CONFIG_DAC_OUTPUT_P_PIN, 0);
#endif

#if defined(GKT_CONFIG_RFID_ENABLE)	\
	&& GKT_CONFIG_RFID_ENABLE	\
	&& defined(GKT_CONFIG_RFID_STANDBY_ENABLE) \
	&& GKT_CONFIG_RFID_STANDBY_ENABLE
#if defined(GKT_CONFIG_RFID_QUERY_MODE_ENABLE) && GKT_CONFIG_RFID_QUERY_MODE_ENABLE 					
	gkt_card_polling_control(0);
#if (defined(GKT_CONFIG_RFID_YC5018_KEYPAD_MUTUAL_EXCLUSION)	\
		&& GKT_CONFIG_RFID_YC5018_KEYPAD_MUTUAL_EXCLUSION)	\
	|| (defined(GKT_CONFIG_RFID_YC5018_PROXIMITY_SENSOR_MUTUAL_EXCLUSION)	\
		&& GKT_CONFIG_RFID_YC5018_PROXIMITY_SENSOR_MUTUAL_EXCLUSION)	
	gkt_rfid_control(GKT_RFID_CTRL_ENABLE, GKT_RFID_EXT_DATA_KEY);
#endif
#endif
	uint8_t rfid_type;
	gkt_user_amount_s amount;
	
	amount.used_nums = 0;
	gkt_user_get_amount(&amount, GKT_USER_AUTH_ADMIN, GKT_USER_TYPE_MAX);
	
	gkt_get_rfid_type(&rfid_type);
#if defined(GKT_CONFIG_RFID_SL2623) && GKT_CONFIG_RFID_SL2623	
	int key_masked;
	if (rfid_type == GKT_RFID_CHIP_TYPE_SL2623) {
		if (gp_window_unreset_data->rfid_standby_mode == GKT_RFID_STANBY_SOFT_POWEROFF) {/*standby poweroff mode*/
			gkt_rfid_control(GKT_RFID_CTRL_DISABLE, GKT_RFID_EXT_DATA_NONE);	
			gkt_rfid_standby_soft_poweroff();
			gkt_rfid_standby_output_change_to_input();
		}	
		else {/*standby lpcd mode*/
			key_masked = gkt_event_is_masked(GKT_EVENT_KEY);
			if (!key_masked)
				gkt_event_mask_single(GKT_EVENT_KEY, GKT_KEY_MASK_F_LED_DETACH);
			
			gkt_rfid_control(GKT_RFID_CTRL_DISABLE, GKT_RFID_EXT_DATA_NONE);
			retval = gkt_rfid_calibrate(1, GKT_RFID_CALIBRATE_STANDBY);
			if (retval != GKT_SUCCESS) 
				gkt_rfid_standby_soft_poweroff();
			else {
				if (amount.used_nums != 0) {
					amount.used_nums = 0;
					gkt_user_get_amount(&amount, GKT_USER_AUTH_MAX, GKT_USER_TYPE_CARD);
					if (amount.used_nums == 0) {
						gkt_rfid_control(GKT_RFID_CTRL_DISABLE, GKT_RFID_EXT_DATA_NONE);
						gkt_rfid_standby_soft_poweroff();
					}
					else
						gkt_rfid_control(GKT_RFID_CTRL_ENABLE, GKT_RFID_EXT_DATA_NONE);
				}
				else 
					gkt_rfid_control(GKT_RFID_CTRL_ENABLE, GKT_RFID_EXT_DATA_NONE);
			}
			gkt_rfid_standby_output_change_to_input();
			
			if (!key_masked) {
				gkt_thread_sleep(100);
				gkt_event_unmask_single(GKT_EVENT_KEY);
			}
		}
	}
#endif
#if defined(GKT_CONFIG_RFID_YC5018) && GKT_CONFIG_RFID_YC5018
	if (rfid_type == GKT_RFID_CHIP_TYPE_YC5018) {
		if (gp_window_unreset_data->rfid_standby_mode == GKT_RFID_STANBY_SOFT_POWEROFF) {/*standby poweroff mode*/
			gkt_rfid_standby_soft_poweroff();
		}
		else {
			gkt_rfid_control(GKT_RFID_CTRL_DISABLE, GKT_RFID_EXT_DATA_NONE);
			
			retval = gkt_rfid_calibrate(1, GKT_RFID_CALIBRATE_STANDBY);
			if (retval != GKT_SUCCESS) 
				gkt_rfid_standby_soft_poweroff();
			else {
				if (amount.used_nums != 0) {
					amount.used_nums = 0;
					gkt_user_get_amount(&amount, GKT_USER_AUTH_MAX, GKT_USER_TYPE_CARD);
					if (amount.used_nums == 0)
						gkt_rfid_standby_soft_poweroff();
				}
			}
		}
		gkt_rfid_standby_output_change_to_input(); 
	} 
#endif	
#endif/*GKT_CONFIG_RFID_ENABLE*/

#if defined(GKT_CONFIG_FPS_ENABLE) && GKT_CONFIG_FPS_ENABLE
	gkt_fpsensor_control(GKT_FPS_CTRL_DISABLE,0);
	gkt_fpsensor_detect();
	gkt_fpsensor_lp_low_power(0,0);
#endif	
	window_data_save();
#if defined(GKT_CONFIG_SLIDING_CLOSURE_MAGNET_LEVEL)
	gkt_sliding_closure_magnet_degauss_sync();
#endif	
}

